/*
** Copyright (C) 2010 Calin Radoni
**
** This file is part of CHScanner.
**
** CHScanner is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** CHScanner is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with CHScanner. If not, see <http://www.gnu.org/licenses/>.
*/

#include "StdAfx.h"
#include "MIPLocatorBin.h"

#include <Winsock2.h>

#include <algorithm>

//---------------------------------------------------------------------------

MIPLocatorBin::MIPLocatorBin(void)
{
	xDataLoaded = false;
	medianValue = 0;
}

MIPLocatorBin::~MIPLocatorBin(void)
{
	CleanUp();
}

//---------------------------------------------------------------------------

void MIPLocatorBin::CleanUp(void)
{
	theList.clear();
}

//---------------------------------------------------------------------------

void MIPLocatorBin::InternalInit(void)
{
	CleanUp();
}

bool MIPLocatorBin::InternalProcessRecord(char *buffIn, unsigned int sizeIn)
{
	MIPRangeCountry rec;
	bool res;

	//if(buffIn==NULL) return false; // commented for speed, the right parameters are passed anyway
	//if(sizeIn==NULL) return false; // commented for speed, the right parameters are passed anyway

	memcpy(&rec.xIpStart, &buffIn[0], 4);
	memcpy(&rec.xIpEnd,   &buffIn[4], 4);
	rec.xCountry[0] = buffIn[8];
	rec.xCountry[1] = buffIn[9];
	rec.xCountry[2] = 0;

	res = true;
	try{
		theList.push_back(rec);
	}
	catch(...){
		res = false;
	}

	return res;
}

bool MIPLocatorBin::InternalSave(void)
{
	return false;
}

//---------------------------------------------------------------------------

int MIPLocatorBin::GetSize(void)
{
	return (int)theList.size();
}

//---------------------------------------------------------------------------

void MIPLocatorBin::Sort(void)
{
	theList.sort();
}

void MIPLocatorBin::FindMiddleValue(void)
{
	MIPRangeCountry rec;
	int count;

	medianValue = 0;
	count       = (int)theList.size() / 2;
	for(iter=theList.begin(); iter!=theList.end() && medianValue==0; iter++){
		if(count==0){
			rec = *iter;
			medianValue = rec.xIpStart;
		}
		else count--;
	}
}

CString MIPLocatorBin::GetCountry(DWORD ipIn)
{
	MIPRangeCountry rec;
	DWORD ip;
	char str[3];
	bool found;

	ip = ntohl(ipIn);

	found = false;
	str[2] = 0;
	if(ip<=medianValue){
		for(iter=theList.begin(); iter!=theList.end() && !found; iter++){
			rec = *iter;
			if(ip>=rec.xIpStart && ip<=rec.xIpEnd){
				str[0] = rec.xCountry[0];
				str[1] = rec.xCountry[1];
				found = true;
			}
		}
	}
	else{
		for(rIter=theList.rbegin(); rIter!=theList.rend() && !found; rIter++){
			rec = *rIter;
			if(ip>=rec.xIpStart && ip<=rec.xIpEnd){
				str[0] = rec.xCountry[0];
				str[1] = rec.xCountry[1];
				found = true;
			}
		}
	}

	return found ? str : "";
}

//---------------------------------------------------------------------------
